package linkedList;

/**
 * Created with IntelliJ IDEA.
 * Description: 单链表
 * User: 王圆豪
 * Date: 2024-09-25
 * Time: 12:08
 */

class ListNode<E> {
    E data;
    ListNode<E> next;

    ListNode(E data) {
        this.data = data;
        this.next = null;
    }
}

public class LinkedList<E> {
    private ListNode<E> head;
    private int size;

    public LinkedList() {
        head = null;
        size = 0;
    }

    // 由数组建立链表
    public void createList(E[] a) {
        for (E element : a) {
            add(element);
        }
    }

    // 添加元素到链表末尾
    public void add(E e) {
        ListNode<E> newNode = new ListNode<>(e);
        if (head == null) {
            head = newNode;
        } else {
            ListNode<E> current = head;
            while (current.next != null) {
                current = current.next;
            }
            current.next = newNode;
        }
        size++;
    }

    // 求链表的长度
    public int size() {
        return size;
    }

    // 设置链表长度
    public void setsize(int nlen) {
        if (nlen < 0) throw new IllegalArgumentException("Length cannot be negative.");
        size = nlen;
    }

    // 获取指定位置的元素
    public E getElem(int i) {
        if (i < 0 || i >= size) throw new IndexOutOfBoundsException();
        ListNode<E> current = head;
        for (int index = 0; index < i; index++) {
            current = current.next;
        }
        return current.data;
    }

    // 设置指定位置的元素
    public void setElem(int i, E e) {
        if (i < 0 || i >= size) throw new IndexOutOfBoundsException();
        ListNode<E> current = head;
        for (int index = 0; index < i; index++) {
            current = current.next;
        }
        current.data = e;
    }

    // 获取元素的序号
    public int getNo(E e) {
        ListNode<E> current = head;
        for (int index = 0; current != null; index++) {
            if (current.data.equals(e)) return index;
            current = current.next;
        }
        return -1; // 未找到
    }

    // 交换指定位置的元素
    public void swap(int i, int j) {
        if (i < 0 || j < 0 || i >= size || j >= size) throw new IndexOutOfBoundsException();
        if (i == j) return;

        ListNode<E> node1 = head, node2 = head;
        for (int index = 0; index < i; index++) node1 = node1.next;
        for (int index = 0; index < j; index++) node2 = node2.next;

        E temp = node1.data;
        node1.data = node2.data;
        node2.data = temp;
    }

    // 插入元素
    public void insert(int i, E e) {
        if (i < 0 || i > size) throw new IndexOutOfBoundsException();
        ListNode<E> newNode = new ListNode<>(e);
        if (i == 0) {
            newNode.next = head;
            head = newNode;
        } else {
            ListNode<E> current = head;
            for (int index = 0; index < i - 1; index++) {
                current = current.next;
            }
            newNode.next = current.next;
            current.next = newNode;
        }
        size++;
    }

    // 删除元素
    public void delete(int i) {
        if (i < 0 || i >= size) throw new IndexOutOfBoundsException();
        if (i == 0) {
            head = head.next;
        } else {
            ListNode<E> current = head;
            for (int index = 0; index < i - 1; index++) {
                current = current.next;
            }
            current.next = current.next.next;
        }
        size--;
    }

    // 转换为字符串
    public String toString() {
        StringBuilder sb = new StringBuilder("[");
        ListNode<E> current = head;
        while (current != null) {
            sb.append(current.data);
            if (current.next != null) sb.append(", ");
            current = current.next;
        }
        sb.append("]");
        return sb.toString();
    }
}

// 主方法测试
class Main {
    public static void main(String[] args) {
        LinkedList<Integer> list = new LinkedList<>();
        Integer[] arr = {1, 2, 3, 4, 5};
        list.createList(arr);

        System.out.println("链表内容: " + list);
        System.out.println("链表长度: " + list.size());

        list.add(6);
        System.out.println("添加元素6后: " + list);

        list.setElem(2, 10);
        System.out.println("设置索引2的元素为10: " + list);

        System.out.println("索引4的元素: " + list.getElem(4));
        System.out.println("值为3的元素的索引: " + list.getNo(3));

        list.swap(1, 3);
        System.out.println("交换索引1和3的元素: " + list);

        list.insert(2, 20);
        System.out.println("在索引2插入元素20: " + list);

        list.delete(3);
        System.out.println("删除索引3的元素: " + list);
    }
}